home *** CD-ROM | disk | FTP | other *** search
- // Quickdraw 3D sample code
- //
- // Nick Thompson, AppleLink: DEVSUPPORT (devsupport@applelink.apple.com)
- //
- // ©1994-5 Apple Computer Inc., All Rights Reserved
-
- // system headers
- #include <Desk.h>
- #include <Dialogs.h>
- #include <DiskInit.h>
- #include <Fonts.h>
- #include <Menus.h>
- #include <PictUtil.h>
- #include <QDOffScreen.h>
- #include <QuickDraw.h>
- #include <SegLoad.h>
- #include <StandardFile.h>
- #include <TextEdit.h>
- #include <ToolUtils.h>
- #include <TextUtils.h>
- #include <Strings.h>
-
- // for QuickDraw 3D
- #include <QD3D.h>
- #include <QD3DMath.h>
- #include <QD3DDrawContext.h>
- #include <QD3DShader.h>
- #include <QD3DTransform.h>
- #include <QD3DGroup.h>
- #include <QD3DCamera.h>
- #include <QD3DPick.h>
- #include <QD3DString.h>
-
- #include "CustomAttributesShell.h"
- #include "CustomAttributesSupport.h"
- #include "MyErrorHandler.h"
-
- #include "CustomAttribute_Lib.h"
-
- //-------------------------------------------------------------------------------------------
- // function prototypes
-
- static void InitToolbox( void ) ;
- static void MainEventLoop( void ) ;
- static void HandleMenuChoice(DocumentPtr theDocument, long menuChoice);
- static void HandleKeyPress(EventRecord *event) ;
- static void HandleOSEvent(EventRecord *event) ;
- void InitDocumentData( DocumentPtr theDocument ) ;
- TQ3Status DocumentDraw3DData( DocumentPtr theDocument ) ;
- void DisposeDocumentData( DocumentPtr theDocument) ;
-
- //-------------------------------------------------------------------------------------------
- //
-
- Boolean gQuitFlag = false ;
- WindowPtr gMainWindow = nil ;
- DocumentRec gDocument ;
-
- //-------------------------------------------------------------------------------------------
- // main()
- // entry point for the application, initialize the toolbox, initialize QuickDraw 3D
- // and enter the main event loop. On exit from the main event loop, we want to call
- // the QuickDraw 3D exit function to clean up QuickDraw 3d.
-
- void main(void)
- {
- TQ3Status myStatus;
- Rect rBounds = { 50, 50, 350, 350 } ;
- Str255 title = "\pSpinning Box" ;
- FSSpec theFileSpec ; // the file we are opening
-
- InitToolbox() ;
-
- if(MetafileFileSpecify( &theFileSpec )) {
-
- SetCursor(*(GetCursor(watchCursor)));
-
- // Initialize QuickDraw 3D, open a connection to the QuickDraw 3D library
- myStatus = Q3Initialize();
- if ( myStatus == kQ3Failure ) {
- DebugStr("\pErInitialize returned failure.");
- ExitToShell() ;
- }
-
- // install the error handler - this gets called whenever
- // an error occurs, which means we don't have to check so
- // much
- Q3Error_Register( MyErrorHandler, 0L );
- Q3Warning_Register( MyWarningHandler, 0L );
-
- /* Go ahead and register all custom attributes */
- RegisterAllCustomAttributes();
-
- // set up our globals
- gQuitFlag = false ;
- gMainWindow = NewCWindow(nil,&rBounds,title,false,noGrowDocProc,(WindowPtr)-1,true,0); ;
-
- // initialise our document structure
- InitDocumentData( &gDocument ) ;
-
- // try to read the file into the main display group
- if( MyNewModelFromFile(&theFileSpec, &gDocument) != NULL ) {
-
- AdjustCamera( &gDocument,
- (gMainWindow->portRect.right - gMainWindow->portRect.left),
- (gMainWindow->portRect.bottom - gMainWindow->portRect.top) ) ;
-
- SetWTitle( gMainWindow, theFileSpec.name );
- ShowWindow( gMainWindow ) ;
- SetPort( gMainWindow ) ;
-
- SetCursor(&qd.arrow) ;
- MainEventLoop();
-
- }
-
- DisposeDocumentData( &gDocument ) ;
-
- UnregisterAllCustomAttributes();
-
- // Close our connection to the QuickDraw 3D library
- myStatus = Q3Exit();
- if ( myStatus == kQ3Failure )
- DebugStr("\pErExit returned failure.");
- }
- }
-
- //-------------------------------------------------------------------------------------------
- //
-
- void InitDocumentData( DocumentPtr theDocument )
- {
- TQ3Point3D myOrigin = { 0, 0, 0 } ;
- TQ3WindowPointPickData data;
-
-
- // sets up the 3d data for the scene
- // Create view for QuickDraw 3D.
- theDocument->fView = MyNewView( gMainWindow );
-
- // the main display group:
- theDocument->fModel = NULL ;
-
-
- // the drawing styles:
- theDocument->fInterpolation = Q3InterpolationStyle_New(kQ3InterpolationStyleNone) ;
- theDocument->fBackFacing = Q3BackfacingStyle_New(kQ3BackfacingStyleRemove ) ;
- theDocument->fFillStyle = Q3FillStyle_New(kQ3FillStyleFilled ) ;
-
-
- theDocument->fGroupScale = 1;
- theDocument->fGroupCenter = myOrigin ;
-
- // set the rotation matrix the identity matrix
- Q3Matrix4x4_SetIdentity(&theDocument->fRotation);
-
- theDocument->fStringObject = NULL;
- theDocument->fName = NULL;
- theDocument->fDescription = NULL;
-
- data.data.sort = kQ3PickSortNone;
- data.data.numHitsToReturn = 1;
- data.data.mask = kQ3PickDetailMaskObject;
-
- data.point.x = 0;
- data.point.y = 0;
-
- data.vertexTolerance =
- data.edgeTolerance = 3;
-
- theDocument->launchNetscape = kQ3False;
-
- theDocument->units = 1.0;
-
- theDocument->fPickObject = Q3WindowPointPick_New(&data);
-
- return ;
-
- bail:
- // either we failed getting the model or the view
- // so we want to quit here
- ExitToShell() ;
-
- }
-
- void DisposeDocumentData( DocumentPtr theDocument)
- {
- Q3Object_Dispose(theDocument->fView) ; // the view for the scene
- Q3Object_Dispose(theDocument->fModel) ; // object in the scene being modelled
- Q3Object_Dispose(theDocument->fInterpolation) ; // interpolation style used when rendering
- Q3Object_Dispose(theDocument->fBackFacing) ; // whether to draw shapes that face away from the camera
- Q3Object_Dispose(theDocument->fFillStyle) ; // whether drawn as solid filled object or decomposed to components
- if(theDocument->fStringObject) {
- Q3CString_EmptyData(&theDocument->fName);
- Q3Object_Dispose(theDocument->fStringObject) ;
- }
- if( theDocument->fDescription ) {
- Q3CString_EmptyData(&theDocument->fDescString);
- Q3Object_Dispose(theDocument->fDescription);
- }
- if(theDocument->fPickObject)
- Q3Object_Dispose(theDocument->fPickObject) ;
- }
- //-----------------------------------------------------------------------------
- // assumes the port is set up before being called
-
- TQ3Status DocumentDraw3DData( DocumentPtr theDocument )
- {
- TQ3Status theStatus ;
-
- Q3View_StartRendering(theDocument->fView) ;
- do {
- theStatus = SubmitScene( theDocument ) ;
- } while (Q3View_EndRendering(theDocument->fView) == kQ3ViewStatusRetraverse );
-
- return theStatus ;
-
-
- }
-
-
- //----------------------------------------------------------------------------------
-
- //-------------------------------------------------------------------------------------------
- //
-
- short HiWrd(long aLong)
- {
- return (((aLong) >> 16) & 0xFFFF) ;
- }
-
- //-------------------------------------------------------------------------------------------
- //
-
- short LoWrd(long aLong)
- {
- return ((aLong) & 0xFFFF) ;
-
- }
-
- //-------------------------------------------------------------------------------------------
- //
-
- void InitToolbox()
- {
- Handle menuBar = nil;
-
- MaxApplZone() ;
- MoreMasters() ; MoreMasters() ; MoreMasters() ;
-
- InitGraf( &qd.thePort );
- InitFonts();
- InitWindows();
- InitCursor();
- InitMenus();
-
- menuBar = GetNewMBar(Menu_Bar);
- SetMenuBar(menuBar);
-
- //AddResMenu(GetMenuHandle(Apple_Menu), 'DRVR');
-
- DrawMenuBar();
-
- FlushEvents( everyEvent, 0 ) ;
- // initialize application globals
-
- gQuitFlag = false;
-
- }
-
-
- //-------------------------------------------------------------------------------------------
- //
- void MainEventLoop()
- {
- EventRecord event;
- WindowPtr window;
- short thePart;
- Rect screenRect, updateRect;
- Point aPoint = {100, 100};
-
- while( !gQuitFlag )
- {
- if (WaitNextEvent( everyEvent, &event, 0, nil ))
- {
-
- switch (event.what) {
- case mouseDown:
-
- thePart = FindWindow( event.where, &window );
-
- switch( thePart ) {
- case inMenuBar:
- HandleMenuChoice(&gDocument,MenuSelect(event.where));
- break;
-
- case inDrag:
-
- screenRect = (**GetGrayRgn()).rgnBBox;
- DragWindow( window, event.where, &screenRect );
- break ;
-
- case inContent:
-
- if (window != FrontWindow())
- SelectWindow( window );
- break ;
-
- case inGoAway:
- if (TrackGoAway( window, event.where )) {
- DisposeWindow ( window );
- gQuitFlag = true;
-
- }
- break ;
-
- default:
- break ;
- }
- break ;
-
-
- case updateEvt:
-
- window = (WindowPtr)event.message;
- updateRect = (**(window->visRgn)).rgnBBox;
- SetPort( window ) ;
- BeginUpdate( window );
- DocumentDraw3DData( &gDocument ) ;
- EndUpdate( window );
-
- break ;
-
- case keyDown:
- case autoKey:
- if (event.modifiers & cmdKey) {
- HandleMenuChoice(&gDocument,
- MenuKey(event.message & charCodeMask));
- } else
- HandleKeyPress(&event);
- break;
-
- case diskEvt:
- if ( HiWrd(event.message) != noErr )
- (void) DIBadMount(aPoint, event.message);
- break;
-
- case osEvt:
- case activateEvt:
- break;
-
-
- }
- }
- else {
- // we received a null event, do some hit testing
- Point mouseLocation;
-
- GetMouse(&mouseLocation);
- if( PtInRect(mouseLocation, &((GrafPtr) window)->portRect) == true) {
- TQ3Point2D pickPoint;
- TQ3WindowPointPickData data;
- TQ3Status status;
- unsigned long numberHits;
-
- data.data.sort = kQ3PickSortNone;
- data.data.numHitsToReturn = 1;
- data.data.mask =
- kQ3PickDetailMaskObject;
-
-
- data.point.x = mouseLocation.h;
- data.point.y = mouseLocation.v;
-
- data.vertexTolerance =
- data.edgeTolerance = 3;
-
- pickPoint.x = mouseLocation.h;
- pickPoint.y = mouseLocation.v;
-
- Q3WindowPointPick_SetPoint(gDocument.fPickObject, &pickPoint);
-
- Q3View_StartPicking(gDocument.fView, gDocument.fPickObject);
-
- do {
- status = SubmitScene( &gDocument ) ;
- } while((Q3View_EndPicking( gDocument.fView)) == kQ3ViewStatusRetraverse );
-
- Q3Pick_GetNumHits(gDocument.fPickObject, &numberHits);
-
- if( numberHits != 0) {
- DisplayCustomAttributes(&gDocument);
- } else {
- /* Delete previously displayed text */
- if( gDocument.fStringObject ) {
- Str255 pascalString;
-
- strcpy((char *) pascalString, gDocument.fName);
- MoveTo(10,10);
- DrawString(c2pstr((char *)pascalString));
-
- Q3CString_EmptyData(&gDocument.fName);
- gDocument.fName = NULL;
- Q3Object_Dispose(gDocument.fStringObject);
- gDocument.fStringObject = NULL;
- }
- if( gDocument.fDescription ) {
- Str255 pascalString;
-
- /* Delete previously displayed url */
- MoveTo(10,30);
- DrawString(gDocument.fURL);
-
- MoveTo(10,50);
- strcpy((char *) pascalString, gDocument.fDescString);
- DrawString(c2pstr((char *)pascalString));
-
- Q3CString_EmptyData(&gDocument.fDescString);
-
- Q3Object_Dispose(gDocument.fDescription);
- gDocument.fDescription = NULL;
- }
- }
- }
- }
- }
- }
-
-
- //-------------------------------------------------------------------------------------------
- //
- void HandleKeyPress(EventRecord *event)
- {
- #pragma unused ( event )
- }
-
- //-------------------------------------------------------------------------------------------
- //
-
- static void HandleMenuChoice(DocumentPtr theDocument, long menuChoice)
- {
- short theMenu;
- short theItem;
-
- if (menuChoice != 0)
- {
- MenuHandle hMenu;
-
- theMenu = HiWord(menuChoice);
- theItem = LoWord(menuChoice);
-
- if( theMenu == Apple_Menu ) {
- Str255 accName;
-
- hMenu = GetMenu(Settings_Menu);
- GetItem(hMenu,theItem,accName);
- OpenDeskAcc(accName);
- } else if( theMenu == File_Menu) {
- switch (theItem)
- {
- case QuitItem:
- gQuitFlag = true;
- break;
-
- case OpenItem:
- {
- FSSpec theFileSpec ; // the file we are opening
-
- if(MetafileFileSpecify( &theFileSpec )) {
- DisposeDocumentData( &gDocument ) ;
-
- InitDocumentData( &gDocument ) ;
-
- // try to read the file into the main display group
- if( MyNewModelFromFile(&theFileSpec, &gDocument) != NULL ) {
-
- AdjustCamera( &gDocument,
- (gMainWindow->portRect.right - gMainWindow->portRect.left),
- (gMainWindow->portRect.bottom - gMainWindow->portRect.top) ) ;
-
- SetWTitle( gMainWindow, theFileSpec.name );
- SetPort( gMainWindow ) ;
-
- DocumentDraw3DData(&gDocument);
-
- SetCursor(&qd.arrow) ;
- }
- }
- }
- break;
- default:
- break;
- }
- } else if(theMenu == Settings_Menu) {
- TQ3TransformObject scaleTransform = NULL;
- TQ3GroupPosition position;
- TQ3Vector3D newScale;
-
- if( theItem != Netscape) {
- Q3Group_GetFirstPositionOfType(theDocument->fModel, kQ3ShapeTypeTransform, &position);
-
- Q3Group_GetPositionObject(theDocument->fModel, position, &scaleTransform);
- Q3ScaleTransform_Get(scaleTransform, &newScale);
- }
-
- hMenu = GetMenu(Settings_Menu);
- switch (theItem)
- {
- case Scale1M:
- CheckItem(hMenu, Scale1M, true);
- CheckItem(hMenu, Scale10M, false);
- CheckItem(hMenu, Scale100M, false);
- CheckItem(hMenu, Scale1KM, false);
- newScale.x = newScale.y = newScale.z = theDocument->units;
- Q3ScaleTransform_Set(scaleTransform, &newScale);
- break;
-
- case Scale10M:
- CheckItem(hMenu, Scale1M, false);
- CheckItem(hMenu, Scale10M, true);
- CheckItem(hMenu, Scale100M, false);
- CheckItem(hMenu, Scale1KM, false);
- newScale.x = newScale.y = newScale.z = theDocument->units / 10.0;
- Q3ScaleTransform_Set(scaleTransform, &newScale);
- break;
-
- case Scale100M:
- CheckItem(hMenu, Scale1M, false);
- CheckItem(hMenu, Scale10M, false);
- CheckItem(hMenu, Scale100M, true);
- CheckItem(hMenu, Scale1KM, false);
- newScale.x = newScale.y = newScale.z = theDocument->units / 100.0;
- Q3ScaleTransform_Set(scaleTransform, &newScale);
- break;
-
- case Scale1KM:
- CheckItem(hMenu, Scale1M, false);
- CheckItem(hMenu, Scale10M, false);
- CheckItem(hMenu, Scale100M, false);
- CheckItem(hMenu, Scale1KM, true);
- newScale.x = newScale.y = newScale.z = theDocument->units / 1000.0;
- Q3ScaleTransform_Set(scaleTransform, &newScale);
- break;
-
- case Netscape:
- hMenu = GetMenu(Settings_Menu);
- if( theDocument->launchNetscape == kQ3True ) {
- theDocument->launchNetscape = kQ3False;
- CheckItem(hMenu, Netscape, false);
- } else {
- theDocument->launchNetscape = kQ3True;
- CheckItem(hMenu, Netscape, true);
- }
- break;
- }
-
- if(scaleTransform) {
- DocumentDraw3DData(theDocument);
- Q3Object_Dispose(scaleTransform);
- }
- }
- HiliteMenu(0);
- }
- }
-